/**
 * @file      gateway_app.c
 * @brief
 * @version   1.0
 * @date      2023.12.14
 *
 * @copyright Copyright (c) 2018 UCchip Technology Co.,Ltd. All rights reserved.
 *
 * Change Logs:
 * Date          Author       Notes
 * 2023.12.14    ucchip       the first version
 *
 */
#include "gateway_app.h"
#include "boot_api.h"
#include "config_api.h"
#include "factory.h"
#include "factory_api.h"
#include "gateway_manager.h"
#include "led_manager.h"
#include "manager_task.h"
#include "net_app.h"
#include "netdev_manager.h"
#include "serial_app.h"
#include "uc_log.h"
#include "watchdog_app.h"
#include "wiota_app.h"
#include "zftp_app.h"
#include <rtthread.h>
#include <rtdevice.h>

void gateway_reboot_alarm_callback(rt_alarm_t alarm, time_t timestamp)
{
    rt_kprintf("gateway reboot alarm callback, gatway will reboot\n");
    watchdog_reboot();
}

int gateway_reboot_time_set(unsigned int hour)
{
    static struct rt_alarm *alarm = RT_NULL;

    if (hour >= 0 && hour <= 23)
    {
        struct rt_alarm_setup setup;
        struct tm wktime;
        struct tm local_wktime;
        time_t wktimestamp = 0;

        rt_memset(&wktime, 0, sizeof(struct tm));
        wktime.tm_year = 2000;
        wktime.tm_mon = 1;
        wktime.tm_mday = 1;
        wktime.tm_hour = hour;
        wktime.tm_min = 0;
        wktime.tm_sec = 0;

        wktimestamp = mktime(&wktime);
        gmtime_r(&wktimestamp, &local_wktime);

        setup.flag = RT_ALARM_DAILY;
        setup.wktime.tm_year = RT_ALARM_TM_NOW;
        setup.wktime.tm_mon = RT_ALARM_TM_NOW;
        setup.wktime.tm_mday = RT_ALARM_TM_NOW;
        setup.wktime.tm_wday = RT_ALARM_TM_NOW;
        setup.wktime.tm_hour = local_wktime.tm_hour;
        setup.wktime.tm_min = local_wktime.tm_min;
        setup.wktime.tm_sec = local_wktime.tm_sec;

        if (alarm == RT_NULL)
        {
            alarm = rt_alarm_create(gateway_reboot_alarm_callback, &setup);
            RT_ASSERT(alarm != RT_NULL);
        }
        else
        {
            rt_alarm_control(alarm, RT_ALARM_CTRL_MODIFY, &setup);
        }
        if (RT_EOK != rt_alarm_start(alarm))
        {
            TRACE_E("start alarm failed");
            return -RT_ERROR;
        }
        TRACE_W("gateway reboot alarm set at %d:%d:%d", wktime.tm_hour, wktime.tm_min, wktime.tm_sec);
    }
    else
    {
        if (alarm != RT_NULL)
        {
            rt_alarm_stop(alarm);
            rt_alarm_delete(alarm);
            alarm = RT_NULL;
            TRACE_W("gateway reboot alarm is closed");
        }
        else
        {
            TRACE_W("gateway reboot alarm is not set");
        }
    }

    return RT_EOK;
}

void print_base_info(void)
{
    gw_base_cfg_t *base_cfg = uc_static_get_gateway_base_cfg();

    TRACE_I("GW Company   : %s", base_cfg->company);
    TRACE_I("GW HW version: %s", base_cfg->hardware_version);
    TRACE_I("GW SW version: %s", base_cfg->software_version);
    TRACE_I("GW Build time: %s", __DATE__ " " __TIME__);
    TRACE_I("GW dev_id    : %u", base_cfg->dev_id);
}

int gateway_enter(void)
{
    gw_auth_cfg_t *auth_info;
    void *wiota_app_handle = RT_NULL;
    void *gateway_manager_handle = RT_NULL;
#ifdef PKG_USING_MYMQTT
    void *net_passthrough_handle = RT_NULL;
#endif
    void *serial_handle = RT_NULL;
    void *led_manager_handle = RT_NULL;

    // gateway_default_debug();
    print_base_info();

    // init wachdog.
#ifdef RT_USING_WDT
    gw_wtd_cfg_t *ori_cfg = uc_static_get_gateway_wtd_cfg();
    if (ori_cfg->wtd_state && !watchdog_app_init())
    {
        watchdog_app_enable();
    }
#endif

    // init factory cfg
    factory_data_init();

    // enter factory mode test
    auth_info = uc_static_get_gateway_auth_cfg();
    if (UC_FACTORY_MODE == auth_info->work_mode)
    {
        factory_test(auth_info);
    }

    netdev_set_default_ip();

    gateway_reboot_time_set(uc_static_get_gateway_timed_cfg()->time);

    // 创建WIoTa app队列
    wiota_app_queue_create();

    // 创建WIoTa app任务
    if (0 != manager_thread_create(&wiota_app_handle, "wiota_app", wiota_app_task, RT_NULL, 512, RT_THREAD_PRIORITY_MAX / 5, 5))
    {
        TRACE_E("wiota_app task create error");
        return 1;
    }
    // 创建gateway manager队列
    gateway_manager_create_queue();

    // 创建gateway manager任务
    if (0 != manager_thread_create(&gateway_manager_handle, "manager", gateway_manager_task, RT_NULL, 512, RT_THREAD_PRIORITY_MAX / 3, 5))
    {
        TRACE_E("manager task create error");
        return 2;
    }

#ifdef PKG_USING_MYMQTT
    // 创建net app队列
    net_app_create_queue();

    // 创建net app任务
    if (0 != manager_thread_create(&net_passthrough_handle, "net_app", net_app_task, RT_NULL, 1024, RT_THREAD_PRIORITY_MAX / 3, 5))
    {
        TRACE_E("net_app task create error");
        return 3;
    }
#endif

    // 创建串口队列
    serial_create_queue();
    // 创建串口任务
    if (0 != manager_thread_create(&serial_handle, "serial_app", serial_app_task, RT_NULL, 512, RT_THREAD_PRIORITY_MAX / 3 - 1, 5))
    {
        TRACE_E("serial_app task create error");
        return 1;
    }

    // 创建LED队列
    // led_manager_create_queue();

    // 创建LED任务
    if (0 != manager_thread_create(&led_manager_handle, "led_mana", led_manager_task, RT_NULL, 256, RT_THREAD_PRIORITY_MAX / 3 + 2, 2))
    {
        TRACE_E("led_mana task create error");
        return 1;
    }

    // 启动各个任务
    rt_thread_startup((rt_thread_t)wiota_app_handle);
    rt_thread_startup((rt_thread_t)gateway_manager_handle);
#ifdef PKG_USING_MYMQTT
    rt_thread_startup((rt_thread_t)net_passthrough_handle);
#endif
    rt_thread_startup((rt_thread_t)serial_handle);
    rt_thread_startup((rt_thread_t)led_manager_handle);
    zftp_trans_startup();
    return 0;
}